(library (vocabulary-filters)
  (export learned?
          contains-tag?
          make-relevance-filter
          make-difficulty-filter
          make-tag-filter
          §learned
          §not-learned
          §hsk1
          §hsk2
          §hsk3
          §hsk4
          §hsk5
          §hsk6)
  (import
   (except (rnrs base))
   (only (guile)
         lambda* λ
         string=
         ;; newline
         )
   ;; (ice-9 pretty-print)
   (srfi srfi-1)  ; list, reduce
   (vector-utils)
   (alist-utils)
   (model))

  (define learned?
    (λ (word)
      (alist-refs word '("metadata" "learned"))))

  (define contains-tag?
    (λ (word tag)
      (vector-contains (alist-refs word '("metadata" "tags"))
                       tag
                       #:equal-test string=)))

  (define make-relevance-filter
    (λ (relevance comparison)
      (λ (words)
        (vector-filter (λ (_index word)
                         ;; (truncated-print word) (newline)
                         (comparison
                          (alist-refs word '("metadata" "relevance"))
                          relevance))
                       words))))

  ;; TODO: generalize make-...-filter
  (define make-difficulty-filter
    (λ (difficulty comparison)
      (λ (words)
        (vector-filter (λ (_index word)
                         ;; (truncated-print word) (newline)
                         (comparison
                          (alist-refs word '("metadata" "difficulty"))
                          difficulty))
                       words))))

  (define §learned
    (λ (words)
      ;; (truncated-print words) (newline)
      (vector-filter (λ (_index word)
                       ;; (truncated-print word) (newline)
                       (learned? word))
                     words)))

  (define §not-learned
    (λ (words)
      ;; (truncated-print words) (newline)
      (vector-filter (λ (_index word)
                       ;; (truncated-print word) (newline)
                       (not (learned? word)))
                     words)))

  (define make-tag-filter
    (λ (. tags)
      (λ (words)
        (vector-filter (λ (_index word)
                         ;; (truncated-print word) (newline)
                         (reduce (λ (current acc)
                                   (or acc current))
                                 #f
                                 (map (λ (tag) (contains-tag? word tag))
                                      tags)))
                       words))))

  (define §hsk1 (make-tag-filter "hsk1"))
  (define §hsk2 (make-tag-filter "hsk2"))
  (define §hsk3 (make-tag-filter "hsk3"))
  (define §hsk4 (make-tag-filter "hsk4"))
  (define §hsk5 (make-tag-filter "hsk5"))
  (define §hsk6 (make-tag-filter "hsk6")))
